package it.tukano.swingdeco.filechooser;

import it.tukano.fun.Tuple2;
import it.tukano.io.FileExt;
import it.tukano.swingdeco.containers.JPanelExt;
import it.tukano.swingdeco.controls.JButtonExt;
import it.tukano.swingdeco.text.JTextFieldExt;
import java.awt.BorderLayout;
import java.awt.Component;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

/**
 * Wraps a file chooser
 * @author pgi
 */
public class JFileChooserExt extends JFileChooser {

    /* Serial version of this class */
    private static final long serialVersionUID = 0;

    /**
     * Instance initializer
     */
    public JFileChooserExt() {
    }
    
    public JFileChooserExt withFilter(Object description, String... extensions) {
        return withFilter(new ExtensionFileFilter(String.valueOf(description), extensions));
    }

    public JFileChooserExt withFilter(FileFilter extensionFileFilter) {
        this.setAcceptAllFileFilterUsed(false);
        this.addChoosableFileFilter(extensionFileFilter);
        return this;
    }

    /**
     * Sets the base directory
     * @param lastSaveFile a file or a directory or null. If file, use the
     * parent of the file. If directory, use that, if null does nothing
     * @return this
     */
    public JFileChooserExt withParentFile(File lastSaveFile) {
        if (lastSaveFile != null) {
            if (!lastSaveFile.isDirectory()) {
                lastSaveFile = lastSaveFile.getParentFile();
            }
            if (lastSaveFile.isDirectory()) {
                this.setCurrentDirectory(lastSaveFile);
            }
        }
        return this;
    }

    /**
     * Shows a dialog that allow the user to select a file. The choosen file will be
     * checked for overwrite and extension.
     * @param parent the parent of the dialog
     * @return this
     */
    public FileExt showCheckedSaveDialog(Component parent, String[] extensions) {
        FileExt selectedFile = null;
        while (selectedFile == null) {
            int answer = this.showSaveDialog(parent);
            if (answer != JFileChooser.APPROVE_OPTION) {
                break;
            }
            File file = this.getSelectedFile();
            if (file == null) {
                break;
            }
            FileExt ext = new FileExt(file);
            if (!ext.hasExtension(extensions)) {
                ext = ext.applyExtension(extensions[0]);
            }
            if(ext.getFile().exists()) {
                int overwrite = JOptionPane.showConfirmDialog(parent, "Overwrite existing file?");
                if(overwrite == JOptionPane.YES_OPTION) {
                    selectedFile = ext;
                    break;
                } else if(overwrite == JOptionPane.CANCEL_OPTION) {
                    selectedFile = null;
                    break;
                } else {
                    selectedFile = null;
                }
            } else {
                selectedFile = ext;
            }
        }
        return selectedFile;
    }

    public FileExt showCheckedOpenDialog(Component mainComponent, String[] extensions) {
        FileExt selectedFile = null;
        int choice = showOpenDialog(mainComponent);
        if(choice == JFileChooser.APPROVE_OPTION) {
            FileExt file = new FileExt(getSelectedFile());
            if(file.getFile().exists() && file.getFile().canRead() && file.hasExtension(extensions)) {
                selectedFile = file;
            }
        }
        return selectedFile;
    }
    
    /** Generate a container with a text field and a button. Pressing the button
     opens this jfilechooser. The selected file path is set as the text of the
     text field
     @return a pair of values. The first is the text field, the second is the
     component holding the text field that must be added to the ui */
    public Tuple2<JTextFieldExt, Component> createFileField() {
        final JTextFieldExt field = new JTextFieldExt(30);
        final JButtonExt button = new JButtonExt("...").scaleFont(0.8);
        button.onAction(new Runnable() {public void run() {
            if(showOpenDialog(button) == JFileChooser.APPROVE_OPTION) {
                field.setString(getSelectedFile());
            }
        }});
        final JPanelExt panel = new JPanelExt(new BorderLayout())
                .append(button, BorderLayout.EAST)
                .append(field, BorderLayout.CENTER);
        return Tuple2.newInstance(field, (Component) panel);
    }
}
